// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT

import { Palette } from "std-widgets.slint";
import { WindowInfo, WindowInfoHelper } from "./ui_utils.slint";
import { StackView, StackPage } from "./controls/stackview.slint";
import { CityListView } from "./city_weather.slint";
import { CityWeather } from "./weather_datatypes.slint";
import { LocationSearchView } from "./location_search.slint";
import { GeoLocation } from "./location_datatypes.slint";
import { AppPalette, AppFonts, AppImages } from "./style/styles.slint";
import { FloatingTextButton } from "./controls/generic.slint";
import { BusyLayerController, BusyLayer } from "./controls/busy-layer.slint";

// Re export for native rust
export { WindowInfo, AppPalette, BusyLayerController, CityWeather, GeoLocation }

component EdgeFloatingTextButton inherits FloatingTextButton {
    out property<length> edge-spacing: 15px;
}

component AnimatedStackPage inherits StackPage {
    // is-active and is-opened are not set as a binding here, only when the value is actually changed.
    // This is to avoid redundant reevaluation of dependent properties and conditional elements.
    // see: https://github.com/slint-ui/slint/issues/5209
    out property<bool> is-active: false;
    out property<bool> is-opened: false;

    // using a helper int property to be able to use animate
    property<int> is-active-value: 0;

    property<duration> animation-duration: 250ms;

    visible: root.is-active;

    init => { root.is-active = (self.is-active_value == 1); }
    changed is-active-value => { root.is-active = (self.is-active_value == 1); }

    states [
        active when self.is-current: {
            is-active-value: 1;

            out {
                animate is-active-value { delay: root.animation-duration; }
            }
        }
    ]

    content := Rectangle {
        changed y => {
            // First open animation is not working properly without the line below. (A bug?)
            // Seems the animation in transition is using old values,
            // and accessing the property somehow forces the update.
            self.y;

            if (root.is-opened != (self.y == 0)) {
                root.is-opened = (self.y == 0);
            }
        }

        y: root.is-current ? 0px : root.height;

        animate y { duration: root.animation-duration; easing: ease-in-out-quad; }

        @children
    }
}

enum PageType {
    Main,
    AddLocation,
}

export component AppWindow inherits Window {
    background: AppPalette.background;
    default-font-size: AppFonts.default-font-size;

    preferred-width: 900px;
    preferred-height: 600px;

    WindowInfoHelper {
        init => {
            // no support for the different modes currently
            // this is to display slint badge in proper colors
            Palette.color-scheme = ColorScheme.dark;
        }
    }

    stack := StackView {
        function show-page(pageType : PageType) {
            if (pageType == PageType.Main) {
                self.current-index = 0;
            }
            else if (pageType == PageType.AddLocation) {
                self.current-index = 1;
            }
        }

        function back-to-main() {
            self.show-page(PageType.Main);
        }

        current-index: 0;
        min-index: 0;

        StackPage {
            is-current: self.check-is-current(stack.current-index);
            init => { self.page-index = stack.insert-page(); }
            visible: self.page-index <= stack.current-index;

            CityListView {}

            // right (refresh) button
            EdgeFloatingTextButton {
                x: parent.width - self.width - self.edge-spacing;
                y: parent.height - self.height - self.edge-spacing;

                icon-source: AppImages.refresh;

                clicked => {
                    BusyLayerController.set-busy();
                    CityWeather.refresh-all();
                }
            }

            // left (add) button
            EdgeFloatingTextButton {
                x: self.edge-spacing;
                y: parent.height - self.height - self.edge-spacing;

                visible: CityWeather.can-add-city;

                icon-source: AppImages.plus;

                clicked => {
                    stack.show-page(PageType.AddLocation);
                }
            }
        }

        AnimatedStackPage {
            is-current: self.check-is-current(stack.current-index);
            init => { self.page-index = stack.insert-page(); }

            location-search-view := LocationSearchView {
                property<bool> is-active: parent.is-active;
                property<bool> is-opened: parent.is-opened;

                changed is-active => {
                    if (self.is-active) {
                        self.clear();
                    }
                }

                changed is-opened => {
                    if (self.is-opened) {
                        self.focus();
                    }
                }

                close-request => {
                    self.clear-focus();
                    stack.back-to-main();
                }

                EdgeFloatingTextButton {
                    x: parent.width - self.width - self.edge-spacing;
                    y: parent.height - self.height - self.edge-spacing;

                    icon-source: AppImages.xmark;

                    clicked => { location-search-view.close-request(); }
                }
            }
        }
    }

    if BusyLayerController.is-busy: BusyLayer {}
}
